package br.ucb.cesbdao.persistencia.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;

import br.ucb.cesbdao.beans.Trabalhador;
import br.ucb.cesbdao.beans.Atendimento;
import br.ucb.cesbdao.beans.Grupo;
import br.ucb.cesbdao.persistencia.AbstractConnectionDAO;
import br.ucb.cesbdao.persistencia.factory.FactoryConnection;
import br.ucb.cesbdao.relatoriosDTO.TrabalhadorDTO;
import br.ucb.cesbdao.servicos.DateUtil;
import br.ucb.cesbdao.servicos.Servicos;
import br.ucb.cesbdao.servicos.TimeUtil;
import br.ucb.cesbdao.visao.HoraDialog;

public class AtendimentoDAO extends AbstractConnectionDAO{

	public AtendimentoDAO(Connection conexao) {
		super(conexao);
	}
	
	public  void addAtendimento(Atendimento atendimento) throws ClassNotFoundException, SQLException{	
		PreparedStatement stm = getConexao().prepareStatement(sqlAdd);
		stm.setInt(1, atendimento.getChavePessoa());
		stm.setString(2, atendimento.getCpf());
		stm.setDate(3,dataSql);
		stm.setString(4,atendimento.getDiaSemana());
		stm.setTime(5,Servicos.verificaHora(atendimento.getHorarioChegada()));
		if(atendimento.getHorarioEntrada() == null)
			stm.setTime(6,null);
		else
			stm.setTime(6,Time.valueOf(atendimento.getHorarioEntrada()));
		if(atendimento.getHorarioSaida() == null)
			stm.setTime(7,null);
		else
			stm.setTime(7,Time.valueOf(atendimento.getHorarioSaida()));
		stm.setInt(8,atendimento.getPrefencial());

		stm.execute();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  void addAtendimento(Atendimento atendimento,Date date) throws ClassNotFoundException, SQLException{	
		java.sql.Date data = new java.sql.Date(date.getTime());
		PreparedStatement stm = getConexao().prepareStatement(sqlAdd);
		stm.setInt(1, atendimento.getChavePessoa());
		stm.setString(2, atendimento.getCpf());
		stm.setDate(3,data);
		stm.setString(4,atendimento.getDiaSemana());
		stm.setTime(5,Servicos.verificaHora(atendimento.getHorarioChegada()));
		if(atendimento.getHorarioEntrada() == null)
			stm.setTime(6,null);
		else
			stm.setTime(6,Time.valueOf(atendimento.getHorarioEntrada()));
		if(atendimento.getHorarioSaida() == null)
			stm.setTime(7,null);
		else
			stm.setTime(7,Time.valueOf(atendimento.getHorarioSaida()));
		stm.setInt(8,atendimento.getPrefencial());

		stm.execute();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  void addAtendimentoChegada(Atendimento atendimento) throws ClassNotFoundException, SQLException{	
		PreparedStatement stm = getConexao().prepareStatement(sqlAddChegada);
		stm.setInt(1, atendimento.getChavePessoa());
		stm.setString(2, atendimento.getCpf());
		stm.setDate(3,dataSql);
		stm.setString(4,atendimento.getDiaSemana());
		stm.setTime(5,Time.valueOf(atendimento.getHorarioChegada()+":00"));
		if(atendimento.getHorarioEntrada() == null)
			stm.setTime(6,null);
		else
			stm.setTime(6,Time.valueOf(atendimento.getHorarioEntrada()));
		if(atendimento.getHorarioSaida() == null)
			stm.setTime(7,null);
		else
			stm.setTime(7,Time.valueOf(atendimento.getHorarioSaida()));
		stm.setInt(8,atendimento.getPrefencial());

		stm.execute();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  void delAtendimento(int id) throws ClassNotFoundException, SQLException{ 
		PreparedStatement stm = getConexao().prepareStatement(sqlDel);
		stm.setInt(1,id);
		stm.execute();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  Atendimento getByIdAtendimento(int id) throws SQLException, ClassNotFoundException{
		Atendimento atendimento = new Atendimento();
		PreparedStatement stm = getConexao().prepareStatement(sqlByIDAtendimento);
		stm.setInt(1, id);
		ResultSet rs = stm.executeQuery();
		if(rs.next()){
			atendimento = preencheAtendimento(rs);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimento;
	}
	public  ArrayList<Atendimento> getAll() throws ClassNotFoundException, SQLException{
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		PreparedStatement stm = getConexao().prepareStatement(sqlAll);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;

	}
	public  ArrayList<Atendimento> getEspera() throws ClassNotFoundException, SQLException{
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		PreparedStatement stm = getConexao().prepareStatement(sqlByEspera);
		stm.setDate(1,dataSql);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;

	}
	public  ArrayList<Atendimento> getByChavePessoa() throws ClassNotFoundException, SQLException{
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByChavePessoa);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	private  Atendimento preencheAtendimento(ResultSet rs) throws SQLException {
		//Na hora de pegar a data não se tem como já spegar direto como string
		//caso não der certo tenhu que fazer um metodo para comverter
		return new Atendimento(rs.getInt(1), 
				rs.getInt(2),
				rs.getString(3),
				rs.getString(4),
				rs.getString(5),
				rs.getString(6),
				rs.getString(7),
				rs.getString(8),
				rs.getInt(9));
	}
	public  boolean isVerificaEmAtendimento(Integer idPaciente) throws SQLException, ClassNotFoundException {
		boolean flag = false;
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByChavePessoa);
		stm.setInt(1, idPaciente);
		ResultSet rs = stm.executeQuery();
		if(rs.first())
			if(rs.getString("horarioEntrada") != null && rs.getString("horarioSaida") == null)
				flag = true;
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return flag;
	}
	public  boolean isVerificaEmAtendimentoAFI(String cpf) throws SQLException, ClassNotFoundException {
		boolean flag = false;
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByCpfAFIToday);
		stm.setString(1, cpf);
		stm.setDate(2,dataSql);
		ResultSet rs = stm.executeQuery();
		if(rs.first())
			if(rs.getString("horarioEntrada") != null && rs.getString("horarioSaida") == null)
				flag = true;
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return flag;
	}
	public  void registraEntrada(int id, String cpf) throws SQLException, ClassNotFoundException {
		
		PreparedStatement stm = getConexao().prepareStatement(sqlRegistraEntrada);
		stm.setString(1,cpf);
		stm.setInt(2, id);
		stm.executeUpdate();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  void upTipo(int id, int tipo) throws SQLException, ClassNotFoundException {
		
		PreparedStatement stm = getConexao().prepareStatement(sqlUpTipo);
		stm.setInt(1,tipo);
		stm.setInt(2, id);
		stm.executeUpdate();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  void registraDesistencia(int id) throws SQLException, ClassNotFoundException {
		
		PreparedStatement stm = getConexao().prepareStatement(sqlRgistraDesistencia);
		stm.setTime(1,Time.valueOf(TimeUtil.getHoraSys()));
		stm.setInt(2, id);
		stm.executeUpdate();
		FactoryConnection.getInstance().closeConexao(stm);
	}
	public  ArrayList<Atendimento> getEmAndamento() throws ClassNotFoundException, SQLException {
		Atendimento atendimento = new Atendimento();

		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByAndamento);
		stm.setDate(1,dataSql);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  void registraHorarioEntrada(int id) throws SQLException, ClassNotFoundException {
		
		PreparedStatement stm = getConexao().prepareStatement(sqlRgistraHoraEntrada);
		stm.setTime(1,Servicos.verificaHora(HoraDialog.getHora()));
		stm.setInt(2, id);
		stm.executeUpdate();
		FactoryConnection.getInstance().closeConexao(stm);

	}
	public  void registraHorarioMarcacao(int id) throws SQLException, ClassNotFoundException {
		
		PreparedStatement stm = getConexao().prepareStatement(sqlRgistraHoraMarcacao);
		stm.setTime(1,Servicos.verificaHora(HoraDialog.getHora()));
		stm.setInt(2, id);
		stm.executeUpdate();
		FactoryConnection.getInstance().closeConexao(stm);

	}
	public  void registraSaida(int id) throws SQLException, ClassNotFoundException {
		
		PreparedStatement stm = getConexao().prepareStatement(sqlRgistraSaida);
		stm.setTime(1,Servicos.verificaHora(HoraDialog.getHora()));
		stm.setInt(2, id);
		stm.executeUpdate();
		FactoryConnection.getInstance().closeConexao(stm);

	}
	public  ArrayList<Atendimento> getByDataHoje() throws ClassNotFoundException, SQLException{
		Atendimento atendimento = new Atendimento();

		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByData);
		stm.setDate(1,dataSql);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;

	}
	public  ArrayList<Atendimento> getByData(Date date) throws SQLException, ClassNotFoundException {
		Atendimento atendimento = new Atendimento();
		java.sql.Date dataSql = new java.sql.Date(date.getTime());
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByData);
		stm.setDate(1,dataSql);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  ArrayList<Atendimento> getDesistentes() throws SQLException, ClassNotFoundException {
		Atendimento atendimento = new Atendimento();

		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByDesistentes);
		stm.setDate(1,dataSql);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  ArrayList<Atendimento> getByAno(int ano) throws ClassNotFoundException, SQLException {
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByAno);
		stm.setInt(1,ano);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  ArrayList<Atendimento> getByPeriodo(Date dateInicio,
			Date dateFim) throws ClassNotFoundException, SQLException {
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByPeriodo);
		stm.setDate(1,new java.sql.Date(dateInicio.getTime()));
		stm.setDate(2,new java.sql.Date(dateFim.getTime()));
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  ArrayList<Atendimento> getByPeriodoAndAFI(Date dateIni,
			Date dateFim,String cpf) throws SQLException, ClassNotFoundException {
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByPeriodoAndCpf);
		stm.setDate(1,new java.sql.Date(dateIni.getTime()));
		stm.setDate(2,new java.sql.Date(dateFim.getTime()));
		stm.setString(3, cpf);
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  ArrayList<TrabalhadorDTO> getByPeriodoAndGrupo(Date dataInicio,
			Date dataFim, Grupo grupo) throws SQLException, ClassNotFoundException {

		String sql = "select p.chavePessoa, p.nomePessoa,count(a.idAtendimento) qtde "+
				"from daoatendimento a, daopessoa p,daotrabalhador t "+
				"where a.cpf = t.cpf " +
				"and t.chavepessoa = p.chavepessoa " +
				"and a.data >= ? and a.data <= ? " +
				"and a.cpf in (select t.cpf "+
				"from daotrabalhador_grupo tg, daopessoa p, daotrabalhador t "+						
				"where tg.chavePessoa = p.chavePessoa and p.chavepessoa = t.chavePessoa "+
				"and tg.idgrupo = ?) "+
				"group by a.cpf;";

		TrabalhadorDTO atendente = new TrabalhadorDTO();
		ArrayList<TrabalhadorDTO> atendentes = new ArrayList<TrabalhadorDTO>();
		
		PreparedStatement stm = getConexao().prepareStatement(sql);
		stm.setDate(1,new java.sql.Date(dataInicio.getTime()));
		stm.setDate(2,new java.sql.Date(dataFim.getTime()));
		stm.setInt(3,grupo.getIdGrupo());
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendente = new TrabalhadorDTO(new Trabalhador(rs.getInt(1), rs.getString(2)), rs.getInt(3));
			atendentes.add(atendente);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendentes;
	}

	public  ResultSet getByPeriodoAndAtendido(Date dataInicio, Date dataFim, Integer id) throws ClassNotFoundException, SQLException {
		PreparedStatement instrucao = getConexao().prepareStatement(sqlByPeriodoAtendido);
		instrucao.setInt(1, id);
		instrucao.setDate(2,new java.sql.Date(dataInicio.getTime()));
		instrucao.setDate(3,new java.sql.Date(dataFim.getTime()));
		ResultSet rs = instrucao.executeQuery();
		return rs;
	}
	
	public  ResultSet getByPeriodoDetalhe(Date dataInicio, Date dataFim) throws ClassNotFoundException, SQLException {
		PreparedStatement instrucao = getConexao().prepareStatement(sqlByPeriodoDetalhe);
		instrucao.setDate(1,new java.sql.Date(dataInicio.getTime()));
		instrucao.setDate(2,new java.sql.Date(dataFim.getTime()));
		ResultSet rs = instrucao.executeQuery();
		return rs;
	}
	
	public  ResultSet getByPeriodoAndAtendidoByAFI(Date dataInicio, Date dataFim, Integer id, Trabalhador atendente) throws ClassNotFoundException, SQLException {
		PreparedStatement instrucao = getConexao().prepareStatement(sqlByPeriodoAtendidoAndAFI);
		instrucao.setInt(1, id);
		instrucao.setDate(2,new java.sql.Date(dataInicio.getTime()));
		instrucao.setDate(3,new java.sql.Date(dataFim.getTime()));
		instrucao.setString(4, atendente.getCpf());
		ResultSet rs = instrucao.executeQuery();
		return rs;
	}

	public  Integer getQuantAtendimentoAFI(String cpf) throws ClassNotFoundException, SQLException {
		Integer quantidade = 0;
		PreparedStatement stm = getConexao().prepareStatement(sqlByCpf);
		stm.setString(1, cpf);
		ResultSet rs = stm.executeQuery();
		if(rs.first())
			quantidade = rs.getInt(1);
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return quantidade;
	}
	public  ArrayList<Atendimento> getByAfiDate(Trabalhador atendente,
			Date date) throws SQLException, ClassNotFoundException {
		
		Atendimento atendimento = new Atendimento();
		ArrayList<Atendimento> atendimentos = new ArrayList<Atendimento>();
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByDateAfi);
		stm.setDate(1,new java.sql.Date(date.getTime()));
		stm.setString(2, atendente.getCpf());
		ResultSet rs = stm.executeQuery();
		while(rs.next()){
			atendimento = preencheAtendimento(rs);
			atendimentos.add(atendimento);
		}
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return atendimentos;
	}
	public  Object getQuantAtendimentoAfiDate(String cpf, Date date) throws SQLException, ClassNotFoundException {
		Integer quantidade = 0;
		
		PreparedStatement stm = getConexao().prepareStatement(sqlByCpfData);
		stm.setString(1, cpf);
		stm.setInt(2,DateUtil.getMes(date));
		ResultSet rs = stm.executeQuery();
		if(rs.first())
			quantidade = rs.getInt(1);
		FactoryConnection.getInstance().closeConexao(stm, rs);
		return quantidade;
	}

	private static final String sqlAdd = "INSERT INTO daoAtendimento VALUES(null,?,?,?,?,?,?,?,?);";
	private static final String sqlAddChegada = "INSERT INTO daoAtendimento VALUES(null,null,?,?,?,?,?,?,?);";
	private static final String sqlDel = "DELETE From daoAtendimento WHERE idAtendimento = ?;";
	private static final String sqlByIDAtendimento = "SELECT *FROM daoAtendimento WHERE idAtendimento = ?;";
	private static final String sqlAll = "SELECT *FROM daoAtendimento;";
	private static final String sqlByChavePessoa = "SELECT *FROM daoAtendimento WHERE chavePessoa = ?;";
	private static final String sqlByCpfAFIToday = "SELECT *FROM daoAtendimento WHERE cpf = ? and data=?;";
	private static final String sqlByCpf = "SELECT count(*) FROM daoAtendimento WHERE cpf = ?;";
	private static final String sqlByCpfData = "SELECT count(*) FROM daoAtendimento WHERE cpf = ? and EXTRACT(month FROM data) = ?;";
	private static final String sqlByEspera = "SELECT *FROM daoAtendimento WHERE horarioEntrada is null and horarioSaida is null and data=?;";
	private static final String sqlByAndamento = "SELECT *FROM daoAtendimento WHERE horarioEntrada is not null and horarioSaida is null and data=?;";
	private static final String sqlByDesistentes = "SELECT *FROM daoAtendimento WHERE horarioEntrada is null and horarioSaida is not null and data=?;";
	private static final String sqlRegistraEntrada = "UPDATE daoAtendimento SET cpf = ? WHERE idAtendimento = ?;";
	private static final String sqlUpTipo = "UPDATE daoAtendimento SET preferencia = ? WHERE idAtendimento = ?;";
	private static final String sqlRgistraDesistencia = "UPDATE daoAtendimento SET horarioSaida=? WHERE idAtendimento = ?;";
	private static final String sqlRgistraSaida = "UPDATE daoAtendimento SET horarioSaida=? WHERE idAtendimento = ?;";
	private static final String sqlRgistraHoraEntrada = "UPDATE daoAtendimento SET horarioEntrada=? WHERE idAtendimento = ?;";
	private static final String sqlRgistraHoraMarcacao = "UPDATE daoAtendimento SET horarioChegada=? WHERE idAtendimento = ?;";
	private static final String sqlByData = "SELECT *FROM daoAtendimento WHERE data = ?;";
	private static final String sqlByAno = "SELECT *FROM daoAtendimento WHERE EXTRACT(year FROM data) = ?;";
	private static final String sqlByPeriodo = "SELECT *FROM daoAtendimento WHERE data >= ? and data <= ?;";
	private static final String sqlByPeriodoAndCpf = "SELECT *FROM daoAtendimento WHERE data >= ? and data <= ? and cpf = ?;";
	private static final String sqlByDateAfi = "SELECT *FROM daoAtendimento WHERE data = ? and cpf = ?;";
	private static java.sql.Date dataSql = new java.sql.Date(DateUtil.getDataAtual().getTime());
	private static String sqlByPeriodoAtendido = 	"select * "+
													"from daopessoa P, daoAtendimento A "+
													"where p.chavepessoa not in (select p.chavePessoa from daopessoa as p, daotrabalhador as t where p.chavepessoa = t.chavepessoa) "+
													"and P.chavepessoa = A.chavepessoa "+
													"and P.chavepessoa = ? "+
													"and A.data >= ? "+
													"and A.data <= ?"+
													"order by A.data;";
	private static String sqlByPeriodoAtendidoAndAFI = "select * "+
			"from daopessoa P, daoAtendimento A "+
			"where p.chavepessoa not in (select p.chavePessoa from daopessoa as p, daotrabalhador as t where p.chavepessoa = t.chavepessoa) "+
			"and P.chavepessoa = A.chavepessoa "+
			"and P.chavepessoa = ? "+
			"and A.data >= ? "+
			"and A.data <= ?"+
			"and A.CPF = ?"+
			"order by A.data;";
	private static String sqlByPeriodoDetalhe = "select * "+
			"from daopessoa P, daoAtendimento A "+
			"where p.chavepessoa not in (select p.chavePessoa from daopessoa as p, daotrabalhador as t where p.chavepessoa = t.chavepessoa) "+
			"and P.chavepessoa = A.chavepessoa "+
			"and A.data >= ? "+
			"and A.data <= ?"+
			"order by A.data;";
}

